#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
GitLab TimescaleDB 启动脚本

提供简单的命令行界面来运行各种GitLab TimescaleDB功能：
- 初始化数据库
- 执行数据同步
- 运行测试
- 查看示例
"""

import os
import sys
from datetime import datetime, timedelta
from pathlib import Path
from typing import Callable, Optional

from loguru import logger

# 添加包路径
sys.path.insert(0, str(Path(__file__).parent))


def print_banner():
    """打印横幅"""
    logger.info("=" * 60)
    logger.info("🚀 GitLab TimescaleDB 数据收集与分析工具")
    logger.info("=" * 60)


def print_menu():
    """打印菜单"""
    logger.info("\n请选择要执行的操作:")
    logger.info("1. 🧪 运行功能测试")
    logger.info("2. 📊 查看使用示例")
    logger.info("3. 🗄️ 初始化数据库")
    logger.info("4. 🔄 执行全量同步 (单实例)")
    logger.info("5. ⚡ 执行增量同步 (单实例)")
    logger.info("6. 🌐 执行多实例同步")
    logger.info("7. 📈 生成分析报告")
    logger.info("8. ❓ 显示帮助信息")
    logger.info("0. 🚪 退出")
    logger.info("-" * 40)


def run_test():
    """运行测试"""
    logger.info("\n🧪 运行功能测试...")
    os.system("python gitlab_timescale/test_gitlab_timescale.py")


def run_examples():
    """运行示例"""
    logger.info("\n📊 运行使用示例...")
    os.system("python gitlab_timescale/examples.py")


def init_database():
    """初始化数据库"""
    logger.info("\n🗄️ 初始化数据库...")
    os.system("python gitlab_timescale/sync_script.py --init-db")


def full_sync():
    """执行全量同步"""
    logger.info("\n🔄 执行全量同步...")
    logger.warning("⚠️ 警告: 全量同步可能需要较长时间，请确保网络连接稳定")
    confirm = input("是否继续? (y/N): ")
    if confirm.lower() in ['y', 'yes']:
        os.system("python gitlab_timescale/sync_script.py --full-sync")
    else:
        logger.info("❌ 已取消全量同步")


def incremental_sync():
    """执行增量同步"""
    logger.info("\n⚡ 执行增量同步...")
    days = input("请输入同步天数 (默认7天): ") or "7"
    try:
        days = int(days)
        os.system(f"python gitlab_timescale/sync_script.py --incremental-sync --days {days}")
    except ValueError:
        logger.error("❌ 无效的天数，请输入数字")


def multi_instance_sync():
    """执行多实例同步"""
    logger.info("\n🌐 执行多实例同步...")
    logger.warning("⚠️ 警告: 多实例同步将并发处理所有配置的GitLab实例")
    logger.info("请确保已在.env文件中正确配置GITLAB_INSTANCES环境变量")
    logger.info("格式: GITLAB_INSTANCES=name1:url1:token1,name2:url2:token2")

    sync_type = input("请选择同步类型 (1=全量同步, 2=增量同步, 默认=增量): ") or "2"

    if sync_type == "1":
        confirm = input("确认执行多实例全量同步? 这可能需要很长时间 (y/N): ")
        if confirm.lower() in ['y', 'yes']:
            os.system("python gitlab_timescale/sync_script.py --multi-instance --full-sync")
        else:
            logger.info("❌ 已取消多实例全量同步")
    elif sync_type == "2":
        days = input("请输入同步天数 (默认7天): ") or "7"
        try:
            days = int(days)
            from datetime import datetime, timedelta
            start_time = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d')
            os.system(f"python gitlab_timescale/sync_script.py --multi-instance --start-time '{start_time}'")
        except ValueError:
            logger.error("❌ 无效的天数，请输入数字")
    else:
        logger.error("❌ 无效的同步类型")


def generate_report():
    """生成分析报告"""
    logger.info("\n📈 生成分析报告...")

    # 选择分析模式
    mode = input("请选择分析模式 (1=单实例, 2=多实例, 默认=单实例): ") or "1"

    days = input("请输入分析天数 (默认30天): ") or "30"
    try:
        days = int(days)
        from datetime import datetime, timedelta
        start_time = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d')

        if mode == "2":
            os.system(f"python gitlab_timescale/sync_script.py --analyze --multi-instance --start-time '{start_time}'")
        else:
            os.system(f"python gitlab_timescale/sync_script.py --analyze --start-time '{start_time}'")
    except ValueError:
        logger.error("❌ 无效的天数，请输入数字")


def run_multi_instance_incremental_sync_with_callback(days: int = 7,
                                                      callback: Optional[Callable[[str], None]] = None) -> dict:
    """执行多实例增量同步（带回调支持）
    
    Args:
        days: 同步天数，默认7天
        callback: 日志回调函数，用于实时显示日志信息
    
    Returns:
        dict: 同步结果
    """
    import logging

    try:
        if callback:
            callback(f"🌐 开始执行多实例增量同步（最近{days}天数据）...")

        # 导入必要的模块
        sys.path.insert(0, str(Path(__file__).parent))
        from gitlab_timescale.config import get_config, setup_logging, validate_config
        from gitlab_timescale.models import TimescaleDBManager
        from gitlab_timescale.collector import SyncConfig
        from gitlab_timescale.sync_script import perform_multi_gitlab_sync, parse_datetime

        # 创建自定义日志处理器来捕获日志消息
        class CallbackLogHandler(logging.Handler):
            def __init__(self, callback_func):
                super().__init__()
                self.callback_func = callback_func

            def emit(self, record):
                if self.callback_func:
                    try:
                        # 格式化日志消息
                        log_message = self.format(record)
                        # 提取有用的信息，去掉时间戳和模块名
                        if '|' in log_message:
                            parts = log_message.split('|')
                            if len(parts) >= 4:
                                message = parts[-1].strip()
                                self.callback_func(message)
                        else:
                            self.callback_func(log_message)
                    except Exception:
                        pass  # 忽略日志处理错误

        # 获取配置
        config = get_config()

        if callback:
            callback("✅ 已加载环境变量文件: .env")

        # 设置日志系统
        config.log.console_output = False  # 禁用控制台输出
        setup_logging(config.log)

        # 添加自定义日志处理器
        if callback:
            custom_handler = CallbackLogHandler(callback)
            custom_handler.setLevel(logging.INFO)

            # 获取根日志记录器并添加处理器
            root_logger = logging.getLogger()
            root_logger.addHandler(custom_handler)

            # 也为特定的模块添加处理器
            for logger_name in ['gitlab_timescale.config', 'gitlab_timescale.models',
                                'gitlab_timescale.collector', '__main__']:
                logger = logging.getLogger(logger_name)
                logger.addHandler(custom_handler)

        # 验证配置
        if not validate_config(config):
            error_msg = "❌ 配置验证失败"
            if callback:
                callback(error_msg)
            return {'status': 'error', 'message': error_msg}

        # 计算开始时间
        start_time = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d')

        # 创建同步配置
        sync_config = SyncConfig(
            full_sync=False,
            start_time=parse_datetime(start_time),
            end_time=None,
            batch_size=50,  # 使用优化后的批量大小
            max_workers=2,  # 使用优化后的并发数
            include_merge_commits=True,
            projects_filter=None
        )

        # 执行多实例同步
        result = perform_multi_gitlab_sync(config, sync_config, dry_run=False, max_workers=2)

        # 清理自定义日志处理器
        if callback:
            root_logger = logging.getLogger()
            handlers_to_remove = [h for h in root_logger.handlers if isinstance(h, CallbackLogHandler)]
            for handler in handlers_to_remove:
                root_logger.removeHandler(handler)

        # 返回结果
        return result

    except Exception as e:
        error_msg = f"❌ 多实例同步异常: {str(e)}"
        if callback:
            callback(error_msg)
        return {'status': 'error', 'message': error_msg}


def show_help():
    """显示帮助信息"""
    logger.info("\n❓ 帮助信息:")
    logger.info("-" * 40)
    logger.info("📋 使用前准备:")
    logger.info("  1. 复制 .env.example 为 .env 并配置相关参数")
    logger.info("  2. 安装依赖: pip install -r requirements.txt")
    logger.info("  3. 确保TimescaleDB数据库可访问")
    logger.info("")
    logger.info("🔧 环境配置:")
    logger.info("  单GitLab实例配置:")
    logger.info("    GITLAB_URL=https://your-gitlab-instance.com")
    logger.info("    GITLAB_ACCESS_TOKEN=your-access-token")
    logger.info("    DATABASE_URL=postgresql://user:password@localhost:5432/dbname")
    logger.info("")
    logger.info("  多GitLab实例配置:")
    logger.info("    GITLAB_INSTANCES=name1:url1:token1,name2:url2:token2")
    logger.info("    GITLAB_DEFAULT_INSTANCE=name1")
    logger.info("    示例:")
    logger.info(
        "    GITLAB_INSTANCES=company:https://gitlab.company.com:glpat-xxx,personal:https://gitlab.com:glpat-yyy")
    logger.info("    GITLAB_DEFAULT_INSTANCE=company")
    logger.info("")
    logger.info("🔧 功能说明:")
    logger.info("  • 功能测试: 验证所有模块是否正常工作")
    logger.info("  • 使用示例: 展示各种功能的使用方法")
    logger.info("  • 初始化数据库: 创建必要的表结构")
    logger.info("  • 全量同步 (单实例): 同步单个GitLab实例的所有历史数据")
    logger.info("  • 增量同步 (单实例): 同步单个GitLab实例的指定天数内数据")
    logger.info("  • 多实例同步: 并发同步所有配置的GitLab实例")
    logger.info("  • 分析报告: 生成单实例或多实例数据统计和分析报告")
    logger.info("")
    logger.info("📁 文件结构:")
    logger.info("  • gitlab_timescale/: 主要包目录")
    logger.info("  • gitlab_timescale_schema.sql: 数据库架构")
    logger.info("  • .env: 环境配置文件")
    logger.info("  • requirements.txt: 依赖包列表")
    logger.info("")
    logger.info("🆘 故障排除:")
    logger.info("  • 导入错误: 检查Python路径和依赖安装")
    logger.info("  • 连接错误: 检查.env文件中的配置")
    logger.info("  • 权限错误: 确保GitLab令牌有足够权限")
    logger.info("  • 数据库错误: 确保TimescaleDB服务正常运行")
    logger.info("  • 多实例配置: 确保GITLAB_INSTANCES格式正确，用逗号分隔多个实例")


def main():
    """主函数"""
    print_banner()

    # 检查环境
    env_file = Path(".env")
    if not env_file.exists():
        logger.warning("\n⚠️ 警告: 未找到 .env 文件")
        logger.info("请复制 .env.example 为 .env 并配置相关参数")
        logger.info("")

    while True:
        print_menu()
        try:
            choice = input("请输入选项 (0-8): ").strip()

            if choice == "0":
                logger.info("\n👋 再见！")
                break
            elif choice == "1":
                run_test()
            elif choice == "2":
                run_examples()
            elif choice == "3":
                init_database()
            elif choice == "4":
                full_sync()
            elif choice == "5":
                incremental_sync()
            elif choice == "6":
                multi_instance_sync()
            elif choice == "7":
                generate_report()
            elif choice == "8":
                show_help()
            else:
                logger.error("\n❌ 无效选项，请重新选择")

        except KeyboardInterrupt:
            logger.info("\n\n👋 用户中断，再见！")
            break
        except Exception as e:
            logger.error(f"\n❌ 发生错误: {e}")

        # 等待用户按键继续
        if choice != "0":
            input("\n按回车键继续...")


if __name__ == "__main__":
    main()
